import os
import re
import sys
import time
from datetime import datetime, timedelta
from pathlib import Path, PureWindowsPath
from typing import List

from PyQt6.QtCore import QDateTime, QLocale, Qt, QThread, pyqtSignal
from PyQt6.QtGui import QPixmap
from PyQt6.QtWidgets import (QApplication, QBoxLayout, QDateEdit,
                             QDateTimeEdit, QFileDialog, QHBoxLayout,
                             QHeaderView, QLabel, QLayout, QLineEdit,
                             QPushButton, QSizePolicy, QTableWidget,
                             QTableWidgetItem, QVBoxLayout, QWidget)

from app.configs.constant import (LABLE_END_DATE, LABLE_START_DATE,
                                  LABLE_UPLOAD_HOURS, LABLE_VIDEO_FOLDER,
                                  QR_CODE_PATH, TABLE_TITLT_LIST, VideoInfo)
from app.utils.utils_kuaishou_upload import kuai_shou_upload
from app.utils.utils_os import OperatingSystem, current_os_name
from app.utils.utils_selenium import driver

is_login: bool = False


class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        # 设置窗口标题
        self.setWindowTitle("我的 PyQt6 程序")
        # 设置窗口大小
        self.setFixedSize(720, 720)
        # 设置中文环境
        self.setLocale(
            QLocale(QLocale.Language.Chinese, QLocale.Country.China))

        self.start_date = ""
        self.end_date = ""
        self.upload_hours = ""
        self.video_folder = ""
        self.table_widget: QTableWidget = None
        self.image_label = None

        self.set_main_layout()

        self.worker = Worker()
        self.worker.pixmapChanged.connect(self.update_image)
        self.worker.start()

    def set_main_layout(self):
        """
            设置主布局
        """

        # 主布局包含两个布局
        # info_layout
        # data_layout
        info_layout = self.get_info_layout()
        data_layout = self.get_data_layout()

        layout = QVBoxLayout()
        layout.addLayout(info_layout)
        layout.addLayout(data_layout)

        layout.setStretch(0, 1)
        layout.setStretch(1, 2)

        self.setLayout(layout)

    def get_info_layout(self):
        """
            信息布局
            包括 开始时间、结束时间、每天上传个数、上传视频目录
            登录信息（扫码登录）
        """

        # 信息布局包含两个布局
        # upload_info
        # login_info
        upload_info_layout = self.get_upload_info_layout()
        login_info_layout = self.get_login_info_layout("请先扫码登录")

        layout = QHBoxLayout()
        layout.addLayout(upload_info_layout)
        layout.addLayout(login_info_layout)

        layout.setStretch(0, 1)
        layout.setStretch(1, 1)

        return layout

    def get_upload_info_layout(self):
        """
            上传信息
            包括 开始时间、结束时间、每天上传个数、上传视频目录
            登录信息（扫码登录）
        """

        # 信息布局包含两个布局
        # upload_info
        # login_info
        start_date_layout = self.get_upload_info_date_widget(LABLE_START_DATE)
        end_date_layout = self.get_upload_info_date_widget(LABLE_END_DATE)

        time_layout = QHBoxLayout()
        time_layout.addLayout(start_date_layout)
        time_layout.addLayout(end_date_layout)

        # 每天几点上传
        upload_hours_layout = self.get_upload_info_time_widget(
            LABLE_UPLOAD_HOURS)

        # 视频目录
        video_folder_layout = self.get_upload_info_video_folder_widget(
            LABLE_VIDEO_FOLDER)

        layout = QVBoxLayout()
        layout.addLayout(time_layout)
        layout.addLayout(upload_hours_layout)
        layout.addLayout(video_folder_layout)
        return layout

    def get_upload_info_date_widget(self, label_name: str, time_format: str = "yyyy-MM-dd") -> QBoxLayout:
        """
            开始日期 & 结束日期
        """
        changed_dict = {
            LABLE_START_DATE: self.set_start_date,
            LABLE_END_DATE: self.set_end_date,
        }

        changed_func = changed_dict.get(label_name)

        label = QLabel(label_name)

        time_edit = QDateTimeEdit()

        # time_edit = QDateEdit()
        time_edit.setCalendarPopup(True)  # 启用日历弹出
        time_edit.setDisplayFormat(time_format)  # 设置显示格式
        # time_edit.setMinimumDateTime(QDateTime.currentDateTime().addDays(1))
        # time_edit.setMaximumDateTime(QDateTime.currentDateTime().addDays(14))
        time_edit.setDateTimeRange(QDateTime.currentDateTime().addDays(
            1), QDateTime.currentDateTime().addDays(14))

        time_edit.setSizePolicy(
            QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)

        # 设置默认值
        changed_func(time_edit.dateTime())

        # 绑定监听函数
        time_edit.dateTimeChanged.connect(changed_func)

        layout = QHBoxLayout()
        layout.addWidget(label)
        layout.addWidget(time_edit)
        layout.setAlignment(Qt.AlignmentFlag.AlignLeft)

        return layout

    def get_upload_info_time_widget(self, label_name: str):
        """
            每天几点上传（整点）
        """

        label = QLabel(label_name)

        line_edit = QLineEdit()
        line_edit.setPlaceholderText("3,15: 表示3点和15点上传视频（一天两个）")
        line_edit.editingFinished.connect(
            lambda: self.set_upload_hours(line_edit))

        layout = QHBoxLayout()
        layout.addWidget(label)
        layout.addWidget(line_edit)

        return layout

    def get_upload_info_video_folder_widget(self, label_name: str):
        """
            视频目录
        """

        label = QLabel(label_name)

        line_edit = QLineEdit("")
        line_edit.setPlaceholderText("请选择待上传视频目录")
        line_edit.focusInEvent = lambda event: self._on_focus_in(
            event, line_edit)

        layout = QHBoxLayout()
        layout.addWidget(label)
        layout.addWidget(line_edit)
        # layout.addWidget(file_dialog)

        return layout

    def get_login_info_layout(self, label_name: str):
        """
            登录信息（扫码登录）
        """

        # 加载图片
        pixmap = QPixmap('path_to_image.jpg')  # 替换为你的图片路径

        # 创建一个QLabel来显示图片
        image_label = QLabel()
        self.image_label = image_label
        image_label.setSizePolicy(
            QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
        image_label.setAlignment(Qt.AlignmentFlag.AlignCenter)

        label = QLabel(label_name)
        # label.setMaximumWidth(30)
        label.setSizePolicy(QSizePolicy.Policy.Expanding,
                            QSizePolicy.Policy.Fixed)
        label.setAlignment(Qt.AlignmentFlag.AlignCenter)

        layout = QVBoxLayout()
        layout.addWidget(image_label)
        layout.addWidget(label)
        layout.setAlignment(Qt.AlignmentFlag.AlignCenter)

        return layout

    def get_data_layout(self):

        # 创建 QTableWidget
        table_widget = QTableWidget()
        self.table_widget = table_widget

        # 设置行数和列数
        # table_widget.setRowCount(4)
        table_widget.setColumnCount(len(TABLE_TITLT_LIST))

        # 可以设置表头
        table_widget.setHorizontalHeaderLabels(TABLE_TITLT_LIST)
        table_widget.horizontalHeader().setSectionResizeMode(
            QHeaderView.ResizeMode.Stretch)

        upload_button = QPushButton("  批量定时发布  ", self)
        upload_button.clicked.connect(self.upload_video)

        # 水平居中按钮
        button_layout = QHBoxLayout()
        button_layout.addWidget(upload_button)
        button_layout.setAlignment(Qt.AlignmentFlag.AlignHCenter)

        layout = QVBoxLayout()
        layout.addWidget(table_widget)
        layout.addLayout(button_layout)

        return layout

    def set_start_date(self, date_time: QDateTime):
        date_time_str = date_time.toString("yyyy-MM-dd")
        self.start_date = date_time_str
        print(f"start_date: {self.start_date}")

    def set_end_date(self, date_time: QDateTime):
        date_time_str = date_time.toString("yyyy-MM-dd")
        self.end_date = date_time_str
        print(f"end_date: {self.end_date}")

    def set_upload_hours(self, line_edit):
        self.upload_hours = line_edit.text()

    def _on_focus_in(self, event, line_edit):
        self.choose_video_folder(line_edit)

        # 调用父类的 focusInEvent 方法
        super().focusInEvent(event)

    def choose_video_folder(self, line_edit: QLineEdit):
        dialog = QFileDialog()
        dialog.setFileMode(QFileDialog.FileMode.Directory)
        dialog.setWindowTitle("选择文件夹")
        dialog.setDirectory("/")

        if dialog.exec():
            selected_folder = dialog.selectedFiles()[0]

            # 设置 video_folder
            self.video_folder = selected_folder

            # 使用传入的 line_edit 设置文本
            line_edit.setText(selected_folder)

            # 清除焦点，避免 _on_focus_in 被重复触发
            line_edit.clearFocus()

        # 根据 self.video_folder 设置数据
        self.set_data_list(self.video_folder)

    def set_data_list(self, video_folder: str):

        data_list: List[VideoInfo] = []
        video_folder_path = Path(video_folder)

        for element_path in video_folder_path.iterdir():

            if element_path.suffix in [".mp4"]:

                os_name = current_os_name()
                path = element_path.as_posix()
                if os_name == OperatingSystem.WINDOWS:
                    path = PureWindowsPath(path).__str__()

                video_info = VideoInfo(
                    name=element_path.name,
                    path=path)

                data_list.append(video_info)

        self.table_widget.setRowCount(len(data_list))

        for row_index, row_data in enumerate(data_list):

            self.table_widget.setItem(
                row_index, 0, QTableWidgetItem(row_data.name))
            self.table_widget.setItem(
                row_index, 1, QTableWidgetItem(row_data.describe))
            self.table_widget.setItem(
                row_index, 2, QTableWidgetItem(row_data.category_major))
            self.table_widget.setItem(
                row_index, 3, QTableWidgetItem(row_data.category_minor))
            self.table_widget.setItem(
                row_index, 4, QTableWidgetItem(row_data.path))

        self.table_widget.update()

    def upload_video(self):

        global is_login

        while True:
            if not is_login:
                # 可以改为提示
                time.sleep(1)
                continue
            break

        # self.start_date
        # self.end_date
        # self.upload_hours
        self.video_folder

        table_data = []
        for row in range(self.table_widget.rowCount()):

            temp_video_info = VideoInfo()
            for column in range(self.table_widget.columnCount()):
                item = self.table_widget.item(row, column)
                text = item.text() if item else ""

                if column == 0:
                    temp_video_info.name = text
                elif column == 1:
                    temp_video_info.describe = text
                elif column == 2:
                    temp_video_info.category_major = text
                elif column == 3:
                    temp_video_info.category_minor = text
                elif column == 4:
                    temp_video_info.path = text

            table_data.append(temp_video_info)

        if self.start_date > self.end_date:
            raise ValueError("开始时间 必须小于 结束时间")

        upload_hours_list = re.split("[,，]", self.upload_hours)

        # for upload_hour in upload_hours_list:
        #     # TODO：验证小时有效性, [0,23]，暂不处理, 24 是另一天的0点，和0冲突

        start_time_str = f"{self.start_date} 00:00:00"
        end_time_str = f"{self.end_date} 00:00:00"

        # 开始日期
        start_time = datetime.strptime(start_time_str, "%Y-%m-%d %H:%M:%S")

        # 结束日期，需要上传
        end_time = datetime.strptime(end_time_str, "%Y-%m-%d %H:%M:%S")

        # 结束日期+1，不需要上传
        end_day = end_time + timedelta(days=1)

        # 先处理时间
        up_time_list = []
        while True:
            if start_time > end_time:
                break

            for up_hour in upload_hours_list:
                temp_time = start_time + timedelta(hours=int(up_hour))
                temp_time_str = temp_time.strftime("%Y-%m-%d %H:%M:%S")
                up_time_list.append(temp_time_str)

            start_time = start_time + timedelta(days=1)

        # 开始上传
        for element_index, element_time in enumerate(up_time_list):
            if element_index == len(table_data):
                # 当前文件数量不满足上传所需
                # 此判断可以提前，加一个确认弹窗，确认继续就有多少传多少
                break

            temp_video_info: VideoInfo = table_data[element_index]

            # 准备上传
            kuai_shou_upload.pre_upload()

            kuai_shou_upload.select_file(temp_video_info.path)
            kuai_shou_upload.set_title(temp_video_info.describe)

            kuai_shou_upload.set_category(
                temp_video_info.category_major, temp_video_info.category_minor)

            kuai_shou_upload.upload(element_time)

    def update_image(self, pixmap):

        pixmap = pixmap.scaledToHeight(
            150, Qt.TransformationMode.SmoothTransformation)
        self.image_label.setPixmap(pixmap)


class Worker(QThread):
    pixmapChanged = pyqtSignal(QPixmap)

    def run(self):

        kuai_shou_upload.login(url="https://cp.kuaishou.com/profile")

        while True:

            global is_login
            is_login = kuai_shou_upload.save_qr_code(QR_CODE_PATH)

            print(f"433 is_login:{is_login}")
            if is_login:
                print(f"435 is_login:{is_login}")
                break

            # 在这里更新 pixmap
            new_pixmap = QPixmap(QR_CODE_PATH)

            self.pixmapChanged.emit(new_pixmap)
            print(f"""\n\n405\n\n""")


if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec())
